home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / sbin / invoke-rc.d < prev    next >
Text File  |  2008-10-14  |  11KB  |  448 lines

  1. #!/bin/sh  
  2. #
  3. # invoke-rc.d.sysvinit - Executes initscript actions
  4. #
  5. # SysVinit /etc/rc?.d version for Debian's sysvinit package
  6. #
  7. # Copyright (C) 2000,2001 Henrique de Moraes Holschuh <hmh@debian.org>
  8. #
  9. # This program is free software; you can redistribute it and/or modify it
  10. # under the terms of the GNU General Public License as published by the Free
  11. # Software Foundation; either version 2 of the License, or (at your option)
  12. # any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful, but
  15. # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17. # for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License along
  20. # with this program; if not, write to the Free Software Foundation, Inc.,
  21. # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  22.  
  23. # Constants
  24. RUNLEVEL=/sbin/runlevel
  25. POLICYHELPER=/usr/sbin/policy-rc.d
  26. INITDPREFIX=/etc/init.d/
  27. RCDPREFIX=/etc/rc
  28.  
  29. # Options
  30. BEQUIET=
  31. MODE=
  32. ACTION=
  33. FALLBACK=
  34. NOFALLBACK=
  35. FORCE=
  36. RETRY=
  37. RETURNFAILURE=
  38. RC=
  39.  
  40. # Shell options
  41. set +e
  42.  
  43. dohelp () {
  44.  # 
  45.  # outputs help and usage
  46.  #
  47. cat <<EOF
  48.  
  49. invoke-rc.d, Debian/SysVinit (/etc/rc?.d) initscript subsystem.
  50. Copyright (c) 2000,2001 Henrique de Moraes Holschuh <hmh@debian.org>
  51.  
  52. Usage:
  53.   invoke-rc.d [options] <basename> <action> [extra parameters]
  54.  
  55.   basename - Initscript ID, as per update-rc.d(8)
  56.   action   - Initscript action. Known actions are:
  57.                 start, [force-]stop, restart,
  58.                 [force-]reload, status
  59.   WARNING: not all initscripts implement all of the above actions.
  60.  
  61.   extra parameters are passed as is to the initscript, following 
  62.   the action (first initscript parameter).
  63.  
  64. Options:
  65.   --quiet
  66.      Quiet mode, no error messages are generated.
  67.   --force
  68.      Try to run the initscript regardless of policy and subsystem
  69.      non-fatal errors.
  70.   --try-anyway
  71.      Try to run init script even if a non-fatal error is found.
  72.   --disclose-deny
  73.      Return status code 101 instead of status code 0 if
  74.      initscript action is denied by local policy rules or
  75.      runlevel constrains.
  76.   --query
  77.      Returns one of status codes 100-106, does not run
  78.      the initscript. Implies --disclose-deny and --no-fallback.
  79.   --no-fallback
  80.      Ignores any fallback action requests by the policy layer.
  81.      Warning: this is usually a very *bad* idea for any actions
  82.      other than "start".
  83.   --help
  84.      Outputs help message to stdout
  85.  
  86. EOF
  87. }
  88.  
  89. printerror () {
  90.  #
  91.  # prints an error message
  92.  #  $* - error message
  93.  #
  94. if test x${BEQUIET} = x ; then
  95.     echo `basename $0`: "$*" >&2
  96. fi
  97. }
  98.  
  99. formataction () {
  100.  #
  101.  # formats a list in $* into $printaction
  102.  # for human-friendly printing to stderr
  103.  # and sets $naction to action or actions
  104.  #
  105. printaction=`echo $* | sed 's/ /, /g'`
  106. if test $# -eq 1 ; then
  107.     naction=action
  108. else
  109.     naction=actions
  110. fi
  111. }
  112.  
  113. querypolicy () {
  114.  #
  115.  # queries policy database
  116.  # returns: $RC = 104 - ok, run
  117.  #          $RC = 101 - ok, do not run
  118.  #        other - exit with status $RC, maybe run if $RETRY
  119.  #          initial status of $RC is taken into account.
  120.  #
  121.  
  122. policyaction="${ACTION}"
  123. if test x${RC} = "x101" ; then
  124.     if test "${ACTION}" = "start" || test "${ACTION}" = "restart" ; then
  125.     policyaction="(${ACTION})"
  126.     fi
  127. fi
  128.  
  129. if test "x${POLICYHELPER}" != x && test -x "${POLICYHELPER}" ; then
  130.     FALLBACK=`${POLICYHELPER} ${BEQUIET} ${INITSCRIPTID} "${policyaction}" ${RL}`
  131.     RC=$?
  132.     formataction ${ACTION}
  133.     case ${RC} in
  134.     0)   RC=104
  135.          ;;
  136.     1)   RC=105
  137.          ;;
  138.     101) if test x${FORCE} != x ; then
  139.         printerror Overriding policy-rc.d denied execution of ${printaction}.
  140.         RC=104
  141.          fi
  142.          ;;
  143.     esac
  144.     if test x${MODE} != xquery ; then
  145.       case ${RC} in
  146.     105) printerror policy-rc.d query returned \"behaviour undefined\",
  147.          printerror assuming \"${printaction}\" is allowed.
  148.          RC=104
  149.          ;;
  150.     106) formataction ${FALLBACK}
  151.          if test x${FORCE} = x ; then
  152.          if test x${NOFALLBACK} = x ; then
  153.              ACTION="${FALLBACK}"
  154.              printerror executing ${naction} \"${printaction}\" instead due to policy-rc.d request.
  155.              RC=104
  156.          else
  157.              printerror ignoring policy-rc.d fallback request: ${printaction}.
  158.              RC=101
  159.          fi
  160.          else
  161.          printerror ignoring policy-rc.d fallback request: ${printaction}.
  162.          RC=104
  163.          fi
  164.          ;;
  165.       esac
  166.     fi
  167.     case ${RC} in
  168.       100|101|102|103|104|105|106) ;;
  169.       *) printerror WARNING: policy-rc.d returned unexpected error status ${RC}, 102 used instead.
  170.          RC=102
  171.      ;;
  172.     esac
  173. else
  174.     if test x${RC} = x ; then 
  175.     RC=104
  176.     fi
  177. fi
  178. return
  179. }
  180.  
  181. verifyparameter () {
  182.  #
  183.  # Verifies if $1 is not null, and $# = 1
  184.  #
  185. if test $# -eq 0 ; then
  186.     printerror syntax error: invalid empty parameter
  187.     exit 103
  188. elif test $# -ne 1 ; then
  189.     printerror syntax error: embedded blanks are not allowed in \"$*\"
  190.     exit 103
  191. fi
  192. return
  193. }
  194.  
  195. ##
  196. ##  main
  197. ##
  198.  
  199. ## Verifies command line arguments
  200.  
  201. if test $# -eq 0 ; then
  202.   printerror syntax error: missing required parameter, --help assumed
  203.   dohelp
  204.   exit 103
  205. fi
  206.  
  207. state=I
  208. while test $# -gt 0 && test ${state} != III ; do
  209.     case "$1" in
  210.       --help)   dohelp 
  211.         exit 0
  212.         ;;
  213.       --quiet)  BEQUIET=--quiet
  214.         ;;
  215.       --force)  FORCE=yes
  216.         RETRY=yes
  217.         ;;
  218.       --try-anyway)
  219.             RETRY=yes
  220.         ;;
  221.       --disclose-deny)
  222.         RETURNFAILURE=yes
  223.         ;;
  224.       --query)  MODE=query
  225.         RETURNFAILURE=yes
  226.         ;;
  227.       --no-fallback)
  228.         NOFALLBACK=yes
  229.         ;;
  230.       --*)    printerror syntax error: unknown option \"$1\"
  231.         exit 103
  232.         ;;
  233.     *)      case ${state} in
  234.         I)  verifyparameter $1
  235.             INITSCRIPTID=$1
  236.             ;;
  237.         II) verifyparameter $1
  238.             ACTION=$1
  239.             ;;
  240.         esac
  241.         state=${state}I
  242.         ;;
  243.     esac
  244.     shift
  245. done
  246.  
  247. if test ${state} != III ; then
  248.     printerror syntax error: missing required parameter
  249.     exit 103
  250. fi
  251.  
  252. #NOTE: It may not be obvious, but "$@" from this point on must expand
  253. #to the extra initscript parameters, except inside functions.
  254.  
  255. ## sanity checks and just-in-case warnings.
  256. case ${ACTION} in
  257.     start|stop|force-stop|restart|reload|force-reload|status)
  258.     ;;
  259.     *)
  260.     if test "x${POLICYHELPER}" != x && test -x "${POLICYHELPER}" ; then
  261.         printerror action ${ACTION} is unknown, but proceeding anyway.
  262.     fi
  263.     ;;
  264. esac
  265.  
  266. ## Verifies if the given initscript ID is known
  267. ## For sysvinit, this error is critical
  268. if test ! -f "${INITDPREFIX}${INITSCRIPTID}" ; then
  269.     printerror unknown initscript, ${INITDPREFIX}${INITSCRIPTID} not found.
  270.     exit 100
  271. fi
  272.  
  273. ## Queries sysvinit for the current runlevel
  274. RL=`${RUNLEVEL} | sed 's/.*\ //'`
  275. if test ! $? ; then
  276.     printerror "could not determine current runlevel"
  277.     if test x${RETRY} = x ; then
  278.     exit 102
  279.     fi
  280.     RL=
  281. fi
  282.  
  283. ## Handles shutdown sequences VERY safely
  284. ## i.e.: forget about policy, and do all we can to run the script.
  285. ## BTW, why the heck are we being run in a shutdown runlevel?!
  286. if test x${RL} = x0 || test x${RL} = x6 ; then
  287.     FORCE=yes
  288.     RETRY=yes
  289.     POLICYHELPER=
  290.     BEQUIET=
  291.     printerror ----------------------------------------------------
  292.     printerror WARNING: invoke-rc.d called during shutdown sequence
  293.     printerror enabling safe mode: initscript policy layer disabled
  294.     printerror ----------------------------------------------------
  295. fi
  296.  
  297. ## Verifies the existance of proper S??initscriptID and K??initscriptID 
  298. ## *links* in the proper /etc/rc?.d/ directory
  299. verifyrclink () {
  300.   #
  301.   # verifies if parameters are non-dangling symlinks
  302.   # all parameters are verified
  303.   #
  304.   doexit=
  305.   while test $# -gt 0 ; do
  306.     if test ! -L "$1" ; then
  307.         printerror not a symlink: $1
  308.         doexit=102
  309.     fi
  310.     if test ! -f "$1" ; then
  311.         printerror dangling symlink: $1
  312.         doexit=102
  313.     fi
  314.     shift
  315.   done
  316.   if test x${doexit} != x && test x${RETRY} = x; then
  317.      exit ${doexit}
  318.   fi
  319.   return 0
  320. }
  321.  
  322. # we do handle multiple links per runlevel
  323. # but we don't handle embedded blanks in link names :-(
  324. if test x${RL} != x ; then
  325.     SLINK=`ls -d -Q ${RCDPREFIX}${RL}.d/S[0-9][0-9]${INITSCRIPTID} 2>/dev/null | xargs`
  326.     KLINK=`ls -d -Q ${RCDPREFIX}${RL}.d/K[0-9][0-9]${INITSCRIPTID} 2>/dev/null | xargs`
  327.     SSLINK=`ls -d -Q ${RCDPREFIX}S.d/S[0-9][0-9]${INITSCRIPTID} 2>/dev/null | xargs`
  328.  
  329.     verifyrclink ${SLINK} ${KLINK} ${SSLINK}
  330. fi
  331.  
  332. testexec () {
  333.   #
  334.   # returns true if any of the parameters is
  335.   # executable (after following links)
  336.   #
  337.   while test $# -gt 0 ; do
  338.     if test -x "$1" ; then
  339.        return 0
  340.     fi
  341.     shift
  342.   done
  343.   return 1
  344. }
  345.  
  346. RC=
  347.  
  348. ###
  349. ### LOCAL INITSCRIPT POLICY: Enforce need of a start entry
  350. ### in either runlevel S or current runlevel to allow start
  351. ### or restart.
  352. ###
  353. case ${ACTION} in
  354.   start|restart)
  355.     if testexec ${SLINK} ; then
  356.     RC=104
  357.     elif testexec ${KLINK} ; then
  358.     RC=101
  359.     elif testexec ${SSLINK} ; then
  360.     RC=104
  361.     fi
  362.   ;;
  363. esac
  364.  
  365. # test if /etc/init.d/initscript is actually executable
  366. if testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
  367.     if test x${RC} = x && test x${MODE} = xquery ; then
  368.         RC=105
  369.     fi
  370.  
  371.     # call policy layer
  372.     querypolicy
  373.     case ${RC} in
  374.         101|104)
  375.            ;;
  376.         *) if test x${MODE} != xquery ; then
  377.            printerror policy-rc.d returned error status ${RC}
  378.            if test x${RETRY} = x ; then
  379.                exit ${RC}
  380.                else
  381.                    RC=102
  382.                fi
  383.            fi
  384.            ;;
  385.     esac
  386. else
  387.     ###
  388.     ### LOCAL INITSCRIPT POLICY: non-executable initscript; deny exec.
  389.     ### (this is common sense, actually :^P )
  390.     ###
  391.     RC=101
  392. fi
  393.  
  394. ## Handles --query
  395. if test x${MODE} = xquery ; then
  396.     exit ${RC}
  397. fi
  398.  
  399.  
  400. setechoactions () {
  401.     if test $# -gt 1 ; then
  402.     echoaction=true
  403.     else
  404.     echoaction=
  405.     fi
  406. }
  407. getnextaction () {
  408.     saction=$1
  409.     shift
  410.     ACTION="$@"
  411. }
  412.  
  413. ## Executes initscript
  414. ## note that $ACTION is a space-separated list of actions
  415. ## to be attempted in order until one suceeds.
  416. if test x${FORCE} != x || test ${RC} -eq 104 ; then
  417.     if testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
  418.     RC=102
  419.     setechoactions ${ACTION}
  420.     while test ! -z "${ACTION}" ; do
  421.         getnextaction ${ACTION}
  422.         if test ! -z ${echoaction} ; then
  423.         printerror executing initscript action \"${saction}\"...
  424.         fi
  425.  
  426.         "${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
  427.         RC=$?
  428.  
  429.         if test ! -z "${ACTION}" ; then
  430.         printerror action \"${saction}\" failed, trying next action...
  431.         fi
  432.     done
  433.     printerror initscript ${INITSCRIPTID}, action \"${saction}\" failed.
  434.     exit ${RC}
  435.     fi
  436.     exit 102
  437. fi
  438.  
  439. ## Handles --disclose-deny
  440. if test ${RC} -eq 101 && test x${RETURNFAILURE} = x ; then
  441.     RC=0
  442. else
  443.     formataction ${ACTION}
  444.     printerror initscript ${naction} \"${printaction}\" not executed.
  445. fi
  446.  
  447. exit ${RC}
  448.